package com.flyqiu.flow.core.handler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.flyqiu.flow.bpmn.element.BaseProcElement;

import com.flyqiu.flow.bpmn.element.ProcGateway;
import com.flyqiu.flow.bpmn.element.SequenceFlow;
import com.flyqiu.flow.bpmn.base.BaseProcElementNode;
import com.flyqiu.flow.model.entity.ru.ProcRuActivity;
import com.flyqiu.flow.model.entity.ru.ProcRuInst;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class BaseComplexGatewayHandler<T extends ProcGateway> extends BaseProcActElementHandler<T, ProcRuActivity> {
    @Override
    protected ProcRuActivity getProcActivity(ProcRuInst procRuInst) {
        List<SequenceFlow> inSequenceFlow = currentElement.getIngoingFlows();
        List<BaseProcElement> result = new ArrayList<>();
        for (SequenceFlow sequenceFlow : inSequenceFlow) {
            findLastLevelElementNode(sequenceFlow, result);
        }
        List<String> flowKeys = result.stream().map(BaseProcElement::getDefKey).collect(Collectors.toList());
        LambdaQueryWrapper<ProcRuActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProcRuActivity::getProcInstId, procContext.getProcInst().getId());
        queryWrapper.in(ProcRuActivity::getDefKey, flowKeys);
        Long count = ruActivityMapper.selectCount(queryWrapper);
        if (count > 0) return null;
        return super.getProcActivity(procRuInst);
    }

    private static void findLastLevelElementNode(BaseProcElement baseProcElement, List<BaseProcElement> result) {
        if (baseProcElement instanceof BaseProcElementNode) {
            result.add(baseProcElement);
            return;
        }
        if (baseProcElement instanceof SequenceFlow) {
            findLastLevelElementNode(((SequenceFlow) baseProcElement).getSourceNode(), result);
        }
    }
}
